#!/usr/bin/env python
# -*- coding:utf-8 -*-

import math

from app import db
from controller.passageInfoController import PassageInfoController
from models.passageInfoModel import PassageInfo
from models.userInfoModel import UserInfo
from models.upvoteInfoModel import UpvoteInfo
from models.careInfoModel import CareInfo
from models.collectionInfoModel import CollectionInfo
from utils import commons
from utils.generate_id import GenerateID
from utils.response_code import RET, error_map_EN, error_map_CN
from utils.loggings import loggings
import os
import time
import re
from utils.validate_operate import verify_operator_object
from controller.userInfoController import UserInfoController

class PassageInfoService(PassageInfoController):
    @classmethod
    def joint_query(cls, **kwargs):
        try:
            filter_list = []
            filter_list.append(cls.IsDelete == 0)
            if kwargs.get('AutoID'):
                filter_list.append(cls.AutoID == kwargs.get('AutoID'))
            if kwargs.get('PostAuthorID'):
                filter_list.append(cls.PostAuthorID == kwargs.get('PostAuthorID'))
            if kwargs.get('PostContent'):
                filter_list.append(cls.PostContent == kwargs.get('PostContent'))
            if kwargs.get('PostTitle'):
                filter_list.append(cls.PostTitle == kwargs.get('PostTitle'))
            if kwargs.get('PostStatus'):
                filter_list.append(cls.PostStatus == kwargs.get('PostStatus'))
            if kwargs.get('UpVoteNum'):
                filter_list.append(cls.UpVoteNum == kwargs.get('UpVoteNum'))
            if kwargs.get('CommentNum'):
                filter_list.append(cls.CommentNum == kwargs.get('CommentNum'))
            if kwargs.get('LookNUM'):
                filter_list.append(cls.LookNUM == kwargs.get('LookNUM'))
            if kwargs.get('IsDelete'):
                filter_list.append(cls.IsDelete == kwargs.get('IsDelete'))
            if kwargs.get('CreateTime'):
                filter_list.append(cls.CreateTime == kwargs.get('CreateTime'))
            if kwargs.get('ModifyTime'):
                filter_list.append(cls.ModifyTime == kwargs.get('ModifyTime'))
          
            page = int(kwargs.get('Page', 1))
            size = int(kwargs.get('Size', 10))
            
            passageInfo_info = db.session.query(PassageInfo.AutoID, PassageInfo.PostAuthorID, PassageInfo.PostContent, PassageInfo.PostTitle, PassageInfo.PostStatus, PassageInfo.UpVoteNum, PassageInfo.CommentNum, PassageInfo.LookNUM, PassageInfo.IsDelete, PassageInfo.CreateTime, PassageInfo.ModifyTime).filter(*filter_list)
            
            count = passageInfo_info.count()
            pages = math.ceil(count / size)
            passageInfo_info = passageInfo_info.limit(size).offset((page - 1) * size).all()
            
            if not passageInfo_info:
                return {'code': RET.NODATA, 'message': error_map_EN[RET.NODATA], 'error': 'No data to update'}
    
            # 处理返回的数据
            results = commons.query_to_dict(passageInfo_info)
            return {'code': RET.OK, 'message': error_map_EN[RET.OK], 'totalCount': count, 'totalPage': pages, 'data': results}
        
        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'error': str(e)}
        finally:
            db.session.close()

    @classmethod
    @verify_operator_object([99, ], UserInfoController)
    def userpublish(cls, **kwargs):
        try:
            filter_list = []
            filter_list.append(cls.IsDelete == 0)
            if kwargs.get('PostAuthorID'):
                filter_list.append(cls.PostAuthorID == kwargs.get('PostAuthorID'))

            page = int(kwargs.get('Page', 1))
            size = int(kwargs.get('Size', 10))
            passageInfo_info = db.session.query(UserInfo.FaceImg,UserInfo.AutoID,UserInfo.FaceImg,UserInfo.IsDelete,UserInfo.UserNickName,
                                                PassageInfo.AutoID, PassageInfo.PostAuthorID, PassageInfo.PostContent,
                                                PassageInfo.PostTitle, PassageInfo.PostStatus, PassageInfo.UpVoteNum,
                                                PassageInfo.CommentNum, PassageInfo.LookNUM, PassageInfo.IsDelete,
                                                PassageInfo.CreateTime, PassageInfo.ModifyTime).join(UserInfo,cls.PostAuthorID == UserInfo.UserID).filter(*filter_list).order_by(cls.CreateTime.desc())

            count = passageInfo_info.count()
            pages = math.ceil(count / size)
            passageInfo_info = passageInfo_info.limit(size).offset((page - 1) * size).all()

            if not passageInfo_info:
                return {'code': RET.NODATA, 'message': error_map_EN[RET.NODATA], 'error': 'No data to update'}

            # 处理返回的数据
            results = commons.query_to_dict(passageInfo_info)
            for i in range(len(results)):
                # results[i].update(
                #     {'CreateTime': int(time.mktime(time.strptime(results[i].pop('CreateTime'), "%Y-%m-%d %H:%M:%S")))})

                img = re.search(r'(?<=(<img src=[\',"])).*?(?=([\',"]))', results[i]['PostContent'])
                if(img):
                    results[i]['img'] = img.group().replace("&amp", "&").replace("&;", "&")
                else:
                    results[i]['img'] = ''
            return {'code': RET.OK, 'message': error_map_EN[RET.OK], 'totalCount': count, 'totalPage': pages,
                    'data': results}

        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'error': str(e)}
        finally:
            db.session.close()

    @classmethod
    def userread_vulnerability_3(cls, **kwargs):
        try:
            filter_list = [cls.IsDelete == 0]
            if kwargs.get('AutoID'):
                filter_list.append(cls.AutoID == kwargs.get('AutoID'))


            filter_list.append(cls.PostAuthorID == UserInfo.UserID)

            passageInfo_info = db.session.query(PassageInfo.AutoID, PassageInfo.PostAuthorID,UserInfo.Account,UserInfo.Password,UserInfo.FaceImg,UserInfo.UserNickName,PassageInfo.PostContent,
                                                PassageInfo.PostTitle, PassageInfo.PostStatus,PassageInfo.PostType,PassageInfo.DeptType ,PassageInfo.UpVoteNum,
                                                PassageInfo.CommentNum, PassageInfo.LookNUM, PassageInfo.IsDelete, UserInfo.Password,
                                                PassageInfo.CreateTime, PassageInfo.ModifyTime).filter(*filter_list)

            passageInfo_info = passageInfo_info.first()
            if not passageInfo_info:
                return {'code': RET.NODATA, 'message': error_map_EN[RET.NODATA], 'error': 'No data to update'}

            results = commons.query_to_dict(passageInfo_info)
            #获取关注点赞收藏状态
            upvote_filterlist=[UpvoteInfo.UUserID == kwargs.get('UserID'),UpvoteInfo.PassageID == kwargs.get('AutoID'),UpvoteInfo.IsDelete == 0]
            upvote_info = db.session.query(UpvoteInfo.IsDelete.label('UpvoteStatus')).filter(*upvote_filterlist)
            upvote_info = upvote_info.first()
            if not upvote_info:
                results['UpvoteStatus'] = 0
            else:
                results['UpvoteStatus'] = 1

            care_filterlist=[CareInfo.UserID == kwargs.get('UserID'),PassageInfo.AutoID == kwargs.get('AutoID'),CareInfo.IsDelete ==0,PassageInfo.IsDelete == 0]
            care_info = db.session.query(CareInfo.UserID).join(PassageInfo,PassageInfo.PostAuthorID == CareInfo.CareUserID).filter(*care_filterlist)
            care_info = care_info.first()
            if not care_info:
                results['CareStatus'] = 0
            else:
                results['CareStatus'] = 1

            collect_filterlist=[CollectionInfo.CUserID == kwargs.get('UserID'),CollectionInfo.PassageID == kwargs.get('AutoID'),CollectionInfo.IsDelete == 0]
            collect_info = db.session.query(CollectionInfo.CUserID).filter(*collect_filterlist)
            # 处理返回的数据更新浏览量
            collect_info = collect_info.first()
            if not collect_info:
                results['CollectStatus'] = 0
            else:
                results['CollectStatus'] = 1
            update_data = {
                'AutoID': results.get('AutoID'),
                'LookNUM': int(results.get('LookNUM')) + 1
            }
            update_res = cls.update(**update_data)
            return {'code': RET.OK, 'message': error_map_EN[RET.OK],
                    'data': results}

        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'error': str(e)}
        finally:
            db.session.close()

    @classmethod
    def userread(cls, **kwargs):
        try:
            filter_list = [cls.IsDelete == 0]
            if kwargs.get('AutoID'):
                filter_list.append(cls.AutoID == kwargs.get('AutoID'))


            filter_list.append(cls.PostAuthorID == UserInfo.UserID)

            passageInfo_info = db.session.query(PassageInfo.AutoID, PassageInfo.PostAuthorID,UserInfo.FaceImg,UserInfo.UserNickName,PassageInfo.PostContent,
                                                PassageInfo.PostTitle, PassageInfo.PostStatus,PassageInfo.PostType,PassageInfo.DeptType ,PassageInfo.UpVoteNum,
                                                PassageInfo.CommentNum, PassageInfo.LookNUM, PassageInfo.IsDelete,
                                                PassageInfo.CreateTime, PassageInfo.ModifyTime).filter(*filter_list)

            passageInfo_info = passageInfo_info.first()
            if not passageInfo_info:
                return {'code': RET.NODATA, 'message': error_map_EN[RET.NODATA], 'error': 'No data to update'}

            results = commons.query_to_dict(passageInfo_info)
            #获取关注点赞收藏状态
            upvote_filterlist=[UpvoteInfo.UUserID == kwargs.get('UserID'),UpvoteInfo.PassageID == kwargs.get('AutoID'),UpvoteInfo.IsDelete == 0]
            upvote_info = db.session.query(UpvoteInfo.IsDelete.label('UpvoteStatus')).filter(*upvote_filterlist)
            upvote_info = upvote_info.first()
            if not upvote_info:
                results['UpvoteStatus'] = 0
            else:
                results['UpvoteStatus'] = 1

            care_filterlist=[CareInfo.UserID == kwargs.get('UserID'),PassageInfo.AutoID == kwargs.get('AutoID'),CareInfo.IsDelete ==0,PassageInfo.IsDelete == 0]
            care_info = db.session.query(CareInfo.UserID).join(PassageInfo,PassageInfo.PostAuthorID == CareInfo.CareUserID).filter(*care_filterlist)
            care_info = care_info.first()
            if not care_info:
                results['CareStatus'] = 0
            else:
                results['CareStatus'] = 1

            collect_filterlist=[CollectionInfo.CUserID == kwargs.get('UserID'),CollectionInfo.PassageID == kwargs.get('AutoID'),CollectionInfo.IsDelete == 0]
            collect_info = db.session.query(CollectionInfo.CUserID).filter(*collect_filterlist)
            # 处理返回的数据更新浏览量
            collect_info = collect_info.first()
            if not collect_info:
                results['CollectStatus'] = 0
            else:
                results['CollectStatus'] = 1
            update_data = {
                'AutoID': results.get('AutoID'),
                'LookNUM': int(results.get('LookNUM')) + 1
            }
            update_res = cls.update(**update_data)
            return {'code': RET.OK, 'message': error_map_EN[RET.OK],
                    'data': results}

        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'error': str(e)}
        finally:
            db.session.close()

    @classmethod
    def pic(cls, **kwargs):
        try:
            pic_file=kwargs.get('file')
            UserID=kwargs.get('UserID')
            if not os.path.exists('./img'):
                os.mkdir('./img')
            if not os.path.exists('./img/'+UserID):
                os.mkdir('./img'+'/'+UserID)
            filepath='./img'+'/'+UserID
            filename=UserID+str(GenerateID.create_random_id())+'.png'
            pic_file.save(filepath+'/'+filename)
            resultpath='/'+UserID
            # 处理返回的数据

            return {'code': RET.OK, 'message': error_map_EN[RET.OK],
                    'data': resultpath+'/'+filename}

        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.IOERR, 'message': error_map_EN[IOError], 'error': str(e)}
        finally:
            db.session.close()

    @classmethod
    def getoneall(cls, **kwargs):
        try:
            filter_list = []
            filter_list.append(cls.IsDelete == 0)
            if kwargs.get('PostAuthorID'):
                filter_list.append(cls.PostAuthorID == kwargs.get('PostAuthorID'))


            page = int(kwargs.get('Page', 1))
            size = int(kwargs.get('Size', 10))

            passageInfo_info = db.session.query(PassageInfo.AutoID, PassageInfo.PostAuthorID, PassageInfo.PostContent,
                                                PassageInfo.PostTitle, PassageInfo.PostStatus, PassageInfo.UpVoteNum,
                                                PassageInfo.CommentNum, PassageInfo.LookNUM, PassageInfo.IsDelete,
                                                PassageInfo.CreateTime, PassageInfo.ModifyTime).filter(*filter_list).order_by(cls.CreateTime.desc())

            count = passageInfo_info.count()
            pages = math.ceil(count / size)
            passageInfo_info = passageInfo_info.limit(size).offset((page - 1) * size).all()
            from controller.userInfoController import UserInfoController
            ks={
                'UserID':kwargs.get('PostAuthorID')
            }
            care_persondata=UserInfoController.get(**ks)

            if not passageInfo_info:
                return {'code': RET.NODATA, 'message': error_map_EN[RET.NODATA], 'error': 'No data to update'}

            # 处理返回的数据
            results = commons.query_to_dict(passageInfo_info)
            return {'code': RET.OK, 'message': error_map_EN[RET.OK], 'totalCount': count, 'totalPage': pages,
                    'person_info':care_persondata.get('data'),'data': results}

        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'error': str(e)}
        finally:
            db.session.close()

    @classmethod
    def fuzzy_query(cls, **kwargs):
        try:
            filter_list = []
            filter_list.append(cls.IsDelete == 0)
            if kwargs.get('KeyWord'):
                filter_list.append(cls.PostTitle.like('%' + kwargs.get('KeyWord') + '%'))
            filter_list.append(cls.PostAuthorID == UserInfo.UserID)
            page = int(kwargs.get('Page', 1))
            size = int(kwargs.get('Size', 10))

            passageInfo_info = db.session.query(PassageInfo.AutoID, PassageInfo.PostAuthorID,
                                                PassageInfo.PostContent, PassageInfo.PostTitle,
                                                PassageInfo.PostStatus, PassageInfo.PostType,
                                                PassageInfo.UpVoteNum,
                                                PassageInfo.CommentNum, PassageInfo.LookNUM, PassageInfo.IsDelete,
                                                PassageInfo.CreateTime, PassageInfo.ModifyTime, UserInfo.FaceImg, UserInfo.UserNickName).filter(*filter_list)

            count = passageInfo_info.count()
            pages = math.ceil(count / size)
            passageInfo_info = passageInfo_info.limit(size).offset((page - 1) * size).all()

            if not passageInfo_info:
                return {'code': RET.NODATA, 'message': error_map_EN[RET.NODATA], 'error': 'No data to update'}

            # 处理返回的数据
            results = commons.query_to_dict(passageInfo_info)
            for i in range(len(results)):

                img = re.search(r'(?<=(<img src=[\',"])).*?(?=([\',"]))', results[i]['PostContent'])
                if (img):
                    results[i]['img'] = img.group().replace("&amp", "&").replace("&;", "&")
                else:
                    results[i]['img'] = ''

            return {'code': RET.OK, 'message': error_map_EN[RET.OK],
                    'data': results, 'totalPage': pages, 'totalCount': count}

        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'error': str(e)}
        finally:
            db.session.close()

    @classmethod
    def recommend(cls, **kwargs):
        try:
            filter_list = [cls.IsDelete == 0, cls.PostAuthorID == UserInfo.UserID]
            # filter_list.append(cls.AutoID in range(1,7))
            # filter_list.append(cls.AutoID.in_(range(1, 7)))
            page = int(kwargs.get('Page', 1))
            size = int(kwargs.get('Size', 10))
            passageInfo_info = db.session.query(PassageInfo.AutoID, PassageInfo.PostTitle, PassageInfo.CreateTime,
                                                PassageInfo.PostContent,PassageInfo.CommentNum,UserInfo.UserNickName).filter(*filter_list).order_by(cls.CreateTime.desc())
            count = passageInfo_info.count()
            pages = math.ceil(count / size)
            passageInfo_info = passageInfo_info.limit(size).offset((page - 1) * size).all()

            if not passageInfo_info:
                return {'code': RET.NODATA, 'message': error_map_EN[RET.NODATA], 'error': 'No data'}
            # 处理返回的数据
            results = commons.query_to_dict(passageInfo_info)
            for i in range(len(results)):
                results[i].update({'passageID': int(results[i].pop('AutoID'))})
                results[i].update({'title': results[i].pop('PostTitle')})
                results[i].update(
                    {'posttime': int(time.mktime(time.strptime(results[i].pop('CreateTime'), "%Y-%m-%d %H:%M:%S")))})
                img = re.search(r'(?<=(<img src=[\',"])).*?(?=([\',"]))', results[i]['PostContent'])
                if (img):
                    results[i]['img'] = img.group().replace("&amp", "&").replace("&;", "&")
                else:
                    results[i]['img'] = ''
            return {'code': RET.OK, 'message': error_map_EN[RET.OK],
                    'data': {'total': count, 'data': results}, 'totalPages': pages, 'totalcount': count}

        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'error': str(e)}
        finally:
            db.session.close()

    @classmethod
    def toprecommend(cls, **kwargs):
        try:
            filter_list = []
            filter_list.append(cls.IsDelete == 0)

            passageInfo_info = db.session.query(PassageInfo.AutoID, PassageInfo.PostTitle, PassageInfo.LookNUM).filter(
                *filter_list).order_by(PassageInfo.LookNUM.desc())
            print(passageInfo_info)
            passageInfo_info = passageInfo_info.limit(6).all()

            if not passageInfo_info:
                return {'code': RET.NODATA, 'message': error_map_EN[RET.NODATA], 'error': 'No data'}

            # 处理返回的数据
            results = commons.query_to_dict(passageInfo_info)
            return {'code': RET.OK, 'message': error_map_EN[RET.OK],
                    'data': results, }

        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'error': str(e)}
        finally:
            db.session.close()

    @classmethod
    def deptquery(cls, **kwargs):
        try:
            filter_list = [cls.IsDelete == 0, cls.PostAuthorID == UserInfo.UserID]
            
            if kwargs.get('Dept'):
                filter_list.append(cls.DeptType == kwargs.get('Dept'))

            page = int(kwargs.get('Page', 1))
            size = int(kwargs.get('Size', 10))
            passageInfo_info = db.session.query(PassageInfo.AutoID, PassageInfo.PostTitle, PassageInfo.CreateTime,
                                                PassageInfo.PostContent, PassageInfo.DeptType,UserInfo.UserNickName,PassageInfo.CommentNum).filter(*filter_list)
            print(passageInfo_info)
            count = passageInfo_info.count()
            pages = math.ceil(count / size)
            passageInfo_info = passageInfo_info.limit(size).offset((page - 1) * size).all()

            if not passageInfo_info:
                return {'code': RET.NODATA, 'message': error_map_EN[RET.NODATA], 'error': 'No data'}

            # 处理返回的数据
            results = commons.query_to_dict(passageInfo_info)
            for i in range(len(results)):
                results[i].update({'passageID': int(results[i].pop('AutoID'))})
                results[i].update({'title': results[i].pop('PostTitle')})
                results[i].update(
                    {'posttime': int(time.mktime(time.strptime(results[i].pop('CreateTime'), "%Y-%m-%d %H:%M:%S")))})
                img = re.search(r'(?<=(<img src=[\',"])).*?(?=([\',"]))', results[i]['PostContent'])
                if(img):
                    results[i]['img'] = img.group().replace("&amp", "&").replace("&;", "&")
                else:
                    results[i]['img'] = ''

            return {'code': RET.OK, 'message': error_map_EN[RET.OK],
                    'data': results, 'totalPages': pages, 'totalcount': count}

        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'error': str(e)}
        finally:
            db.session.close()

    #删除发布文章
    @classmethod
    def deletepassage(cls, **kwargs):
        try:
            #先删除文章再删除相应评论
            deletedata={
                'AutoID':kwargs.get('PassageID')
            }
            res = cls.delete(**deletedata)
            from controller.commentInfoController import CommentInfoController
            if res.get('code') == RET.OK:
                commentdelete={
                    'CommentPostID':kwargs.get('PassageID')
                }
                CommentInfoController.delete(**commentdelete)

            return {'code': RET.OK, 'message': error_map_EN[RET.OK],
                    'data': 'delete successfully'}

        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'error': str(e)}
        finally:
            db.session.close()